package com.tomorrowbbs.controller;

import com.tomorrowbbs.annotation.GlobalInterceptor;
import com.tomorrowbbs.annotation.VerifyParam;
import com.tomorrowbbs.controller.base.ABaseController;
import com.tomorrowbbs.domain.ForumComment;
import com.tomorrowbbs.domain.LikeRecord;
import com.tomorrowbbs.domain.constants.Constants;
import com.tomorrowbbs.domain.dto.ForumCommentDTO;
import com.tomorrowbbs.domain.dto.SessionWebUserDto;
import com.tomorrowbbs.domain.enums.*;
import com.tomorrowbbs.domain.vo.PaginationResultVo;
import com.tomorrowbbs.domain.vo.ResponseVo;
import com.tomorrowbbs.exception.BusinessException;
import com.tomorrowbbs.service.IForumCommentService;
import com.tomorrowbbs.service.ILikeRecordService;
import com.tomorrowbbs.utils.StringTools;
import com.tomorrowbbs.utils.SysCacheUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/comment")
public class ForumCommentController extends ABaseController {

    @Autowired
    private IForumCommentService forumCommentService;
    @Autowired
    private ILikeRecordService likeRecordService;

    @RequestMapping("/loadComment")
    @GlobalInterceptor(checkParams = true)
    public ResponseVo loadComment(HttpSession session,
                                  @VerifyParam(required = true) String articleId,
                                  Integer pageNo,
                                  Integer orderType) {
        final String ORDER_TYPE0 = "good_count desc,comment_id asc";
        final String ORDER_TYPE1 = "comment_id desc";

        if (!SysCacheUtils.getSysSetting().getCommentSetting().getCommentOpen()) {
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }

        ForumComment comment = new ForumComment();
        comment.setArticleId(articleId);
        String orderBy = orderType == null || orderType == Constants.ZERO ? ORDER_TYPE0 : ORDER_TYPE1;
        comment.setOrderBy("top_type desc, " + orderBy);

        //用户信息
//        SessionWebUserDto userDto = getUserInfoFromSession(session);
        SessionWebUserDto userDto = getUserInfoFromSession(session);
        if (userDto != null) {
            comment.setCurrentUserId(userDto.getUserId());
            comment.setQueryLikeType(true);
        } else {
            comment.setStatus(ArticleStatusEnum.AUDIT.getStatus());
        }
        comment.setPageNo(pageNo);
        comment.setPageSize(PageSize.SIZE50.getSize());
        comment.setPCommentId(0l);
        comment.setLoadChildren(true);
        //当前页面
        if (pageNo == null) {
            pageNo = Constants.ONE;
        }
        comment.setPageNo(pageNo);
//        return  getSuccessResponseVo(forumCommentService.selectForumCommentList(comment));
        // 查询评论列表
        List<ForumComment> forumComments = forumCommentService.selectForumCommentList(comment);
        // 获取总记录数
        int totalCount = forumCommentService.countForumComments(comment);
        // 将评论列表封装为 DTO
        List<ForumCommentDTO> forumCommentDTO = convertToDTO(forumComments);
        // 构建分页结果
        PaginationResultVo<ForumCommentDTO> paginationResultVo = getCommentPaginationResultVo(pageNo, totalCount, forumCommentDTO, PageSize.SIZE50.getSize());
        return getSuccessResponseVo(convert2PaginationVO(paginationResultVo, ForumCommentDTO.class));

    }

    /*
     * 评论点赞*/
    @RequestMapping("/doLike")
    @GlobalInterceptor(checkParams = true, checkLogin = true)
    public ResponseVo doLike(HttpSession session, @VerifyParam(required = true) Long commentId) {
        SessionWebUserDto userDto = getUserInfoFromSession(session);
        String objectId = String.valueOf(commentId);
        likeRecordService.doLike(objectId, userDto.getUserId(), userDto.getNickName(), OperRecordOpTypeEnum.COMMENT_LIKE);

        LikeRecord likeRecord = new LikeRecord();
        likeRecord.setObjectId(objectId);
        likeRecord.setUserId(userDto.getUserId());
        likeRecord.setOpType(OperRecordOpTypeEnum.COMMENT_LIKE.getType());
        LikeRecord likeRecord1 = likeRecordService.selectLikeRecord(likeRecord);

        ForumComment comment = forumCommentService.selectForumCommentByCommentId(commentId);
        comment.setLikeType(likeRecord1 != null ? Constants.ZERO : Constants.ONE);
        return getSuccessResponseVo(comment);
    }

    /*
    * 评论置顶*/
    @RequestMapping("/changeTopType")
    @GlobalInterceptor(checkParams = true, checkLogin = true)
    public ResponseVo changeTopType(HttpSession session,
                                    @VerifyParam(required = true) Long commentId,
                                    @VerifyParam(required = true) Integer topType){
        forumCommentService.changeTopType(getUserInfoFromSession(session).getUserId(), commentId, topType);

        return getSuccessResponseVo(null);
    }

    /*
    * 发布评论*/
    @RequestMapping("/postComment")
    @GlobalInterceptor(checkParams = true, checkLogin = true)
    public ResponseVo postComment(HttpSession session,
                                  @VerifyParam(required = true) String articleId,
                                  @VerifyParam(required = true) Long pCommentId,
                                  @VerifyParam(min = 1,max = 1000) String content,
                                  MultipartFile image,
                                  String replyUserId){
        if(!SysCacheUtils.getSysSetting().getCommentSetting().getCommentOpen()){
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }
        if(image == null && StringTools.isEmpty(content)){
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }

        SessionWebUserDto  userDto = getUserInfoFromSession(session);
        content = StringTools.escapeHtml(content);
        ForumComment comment = new ForumComment();
        comment.setUserId(userDto.getUserId());
        comment.setNickName(userDto.getNickName());
        comment.setUserIpAddress(userDto.getProvince());
        comment.setPCommentId(pCommentId);
        comment.setArticleId(articleId);
        comment.setContent(content);
        comment.setReplyUserId(replyUserId);
        comment.setTopType(CommentTopTypeEnum.NO_TOP.getType());

        forumCommentService.postComment(comment,image);

        if(pCommentId != 0){
            ForumComment forumComment = new ForumComment();
            forumComment.setPCommentId(pCommentId);
            forumComment.setArticleId(articleId);
            forumComment.setOrderBy("comment_id asc");
            List<ForumComment> children = forumCommentService.selectForumCommentList(forumComment);
            return getSuccessResponseVo(children);
        }

        return getSuccessResponseVo(comment);
    }

    /*
     * 将查询结果封装*/
    private List<ForumCommentDTO> convertToDTO(List<ForumComment> comments) {
        return comments.stream().map(this::convertSingleToDTO).collect(Collectors.toList());
    }

    private ForumCommentDTO convertSingleToDTO(ForumComment comment) {
        ForumCommentDTO dto = new ForumCommentDTO();
        dto.setCommentId(comment.getCommentId());
        dto.setPCommentId(comment.getPCommentId());
        dto.setArticleId(comment.getArticleId());
        dto.setContent(comment.getContent());
        dto.setImgPath(comment.getImgPath());
        dto.setUserId(comment.getUserId());
        dto.setNickName(comment.getNickName());
        dto.setUserIpAddress(comment.getUserIpAddress());
        dto.setReplyUserId(comment.getReplyUserId());
        dto.setReplyNickName(comment.getReplyNickName());
        dto.setTopType(comment.getTopType());
        dto.setPostTime(comment.getPostTime());
        dto.setGoodCount(comment.getGoodCount());
        dto.setStatus(comment.getStatus());
        dto.setLikeType(comment.getLikeType());
        // 处理子评论
        if (comment.getChildren() != null) {
            dto.setChildren(convertToDTO(comment.getChildren()));
        }

        return dto;
    }

    /*构建分页对象*/
    private static PaginationResultVo<ForumCommentDTO> getCommentPaginationResultVo(Integer pageNo, int totalCount, List<ForumCommentDTO> commentDto, int pageSize) {
        PaginationResultVo<ForumCommentDTO> paginationResultVo = new PaginationResultVo<>();
        paginationResultVo.setTotalCount(totalCount);
        paginationResultVo.setPageSize(pageSize);
        paginationResultVo.setPageNo(pageNo);
        paginationResultVo.setPageTotal((int) Math.ceil((double) totalCount / paginationResultVo.getPageSize()));
        paginationResultVo.setList(commentDto);
        return paginationResultVo;
    }

}














